from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from rest_framework.views import APIView
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi

from .models import CanvasElement
from .serializers import (
    CanvasElementSerializer,
    CreateCanvasElementSerializer,
    BatchUpdateElementSerializer,
    BatchUpdateResultSerializer, UpdateCanvasElementSerializer
)
from ..utils.response_utils import api_response, ResponseCode


class ListCanvasElementView(APIView):
    """
    画布元素列表接口
    """

    @swagger_auto_schema(
        operation_description="获取画布元素列表，可根据画布ID过滤",
        manual_parameters=[
            openapi.Parameter('canvas_id', openapi.IN_QUERY, type=openapi.TYPE_STRING, description="画布ID，必填",
                              required=True)
        ],
        responses={
            200: CanvasElementSerializer,
            500: openapi.Response(description="服务器错误"),
        },
        tags=["画布元素管理"]
    )
    def get(self, request):
        try:
            canvas_id = request.query_params.get('canvas_id')

            # 检查 canvas_id 是否为字符串且非空
            if not isinstance(canvas_id, str) or not canvas_id.strip():
                return api_response(ResponseCode.BAD_REQUEST, "参数错误：canvas_id 必须是非空字符串")

            queryset = CanvasElement.objects.filter(canvas_id=canvas_id).order_by('z_index')
            serializer = CanvasElementSerializer(queryset, many=True)
            return api_response(ResponseCode.SUCCESS, "获取成功", serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class CreateCanvasElementView(APIView):
    """
    创建画布元素接口
    """

    @swagger_auto_schema(
        operation_description="创建新的画布元素",
        request_body=CreateCanvasElementSerializer,
        responses={
            200: CanvasElementSerializer,
            400: openapi.Response(description="参数错误"),
        },
        tags=["画布元素管理"]
    )
    def post(self, request):
        try:
            serializer = CreateCanvasElementSerializer(data=request.data)
            if serializer.is_valid():
                element = serializer.save()
                full_serializer = CanvasElementSerializer(element)
                return api_response(ResponseCode.SUCCESS, "创建成功", full_serializer.data)
            return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, f"服务器错误: {str(e)}")


class CanvasElementDetailView(APIView):
    """
    画布元素详情接口
    """

    @swagger_auto_schema(
        operation_description="获取画布元素详情",
        manual_parameters=[
            openapi.Parameter('element_id', openapi.IN_PATH, type=openapi.TYPE_STRING, description="画布元素ID")
        ],
        responses={
            200: CanvasElementSerializer,
            404: openapi.Response(description="画布元素不存在"),
            500: openapi.Response(description="服务器错误"),
        },
        tags=["画布元素管理"]
    )
    def get(self, request, element_id):
        try:
            element = CanvasElement.objects.get(id=element_id)
            serializer = CanvasElementSerializer(element)
            return api_response(ResponseCode.SUCCESS, "获取成功", serializer.data)
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "画布元素不存在")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class UpdateCanvasElementView(APIView):
    """
    更新画布元素接口
    """

    @swagger_auto_schema(
        operation_description="更新画布元素信息",
        request_body=BatchUpdateElementSerializer,
        responses={
            200: BatchUpdateResultSerializer,
            400: openapi.Response(description="参数错误"),
            404: openapi.Response(description="部分元素不存在"),
        },
        tags=["画布元素管理"]
    )
    def put(self, request):
        try:
            serializer = BatchUpdateElementSerializer(data=request.data)
            if not serializer.is_valid():
                return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")

            success_elements = []
            failed_ids = {}

            with transaction.atomic():
                for element_data in serializer.validated_data['elements']:
                    element_id = element_data.get('id')
                    try:
                        element = CanvasElement.objects.get(id=element_id)
                        #TODO: 判断元素是否锁定可见
                        element_serializer = UpdateCanvasElementSerializer(
                            element,
                            data=element_data,
                            partial=True
                        )

                        if element_serializer.is_valid():
                            updated_element = element_serializer.save()
                            success_elements.append(updated_element)
                        else:
                            failed_ids[element_id] = element_serializer.errors

                    except ObjectDoesNotExist:
                        failed_ids[element_id] = "元素不存在"
                    except Exception as e:
                        failed_ids[element_id] = str(e)

            result_serializer = BatchUpdateResultSerializer({
                'updated_elements': success_elements,
                'failed': failed_ids
            })

            if failed_ids:
                msg = f"部分更新成功：成功 {len(success_elements)} 个，失败 {len(failed_ids)} 个"
                return api_response(ResponseCode.BAD_REQUEST, msg, result_serializer.data)

            return api_response(ResponseCode.SUCCESS, "全部更新成功", result_serializer.data)

        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR,f"服务器错误: {str(e)}")


class DeleteCanvasElementView(APIView):
    """
    删除画布元素接口
    """

    @swagger_auto_schema(
        operation_description="删除画布元素",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['element_ids'],
            properties={
                'element_ids': openapi.Schema(
                    type=openapi.TYPE_ARRAY,
                    items=openapi.Schema(type=openapi.TYPE_STRING),
                    description="画布元素ID列表"
                ),
            }
        ),
        responses={
            200: openapi.Response(description="删除成功"),
            404: openapi.Response(description="部分画布元素不存在"),
        },
        tags=["画布元素管理"]
    )
    def delete(self, request):
        element_ids = request.data.get('element_ids', [])
        if not element_ids or not isinstance(element_ids, list):
            return api_response(ResponseCode.BAD_REQUEST, "参数错误")
        not_found_ids = []
        for element_id in element_ids:
            try:
                element = CanvasElement.objects.get(id=element_id)
                element.delete()
            except ObjectDoesNotExist:
                not_found_ids.append(element_id)
        if not_found_ids:
            return api_response(
                ResponseCode.NOT_FOUND,
                f"成功删除画布元素: {len(element_ids) - len(not_found_ids)}个，未找到画布元素ID: {', '.join(not_found_ids)}"
            )
        return api_response(ResponseCode.SUCCESS, "删除成功")
